package org.lazydoc.plugin;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.commons.beanutils.BeanUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.*;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.artifact.MavenMetadataSource;
import org.lazydoc.config.Config;
import org.lazydoc.config.PrinterConfig;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
@Mojo(name = "document", defaultPhase = LifecyclePhase.COMPILE, executionStrategy = "always")
@Execute(goal = "document", phase = LifecyclePhase.COMPILE)
public class LazyDocMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", readonly = true)
protected MavenProject project;
@Component
private ArtifactResolver artifactResolver;
@Component
private ArtifactFactory artifactFactory;
@Component
private ArtifactMetadataSource metadataSource;
@Parameter(readonly = true, required = true, defaultValue = "${localRepository}")
private ArtifactRepository localRepository;
@Parameter(readonly = true, required = true, defaultValue = "${project.remoteArtifactRepositories}")
private List<ArtifactRepository> remoteRepositories;
@Component
private MavenProjectBuilder projectBuilder;
@Parameter(readonly = true, defaultValue = "${plugin.artifacts}")
private List<Artifact> pluginDependencies;
@Parameter(property = "project.compileClasspathElements", required = true, readonly = true)
private List<String> classpath;
@Parameter
private Config config;
@Parameter
private List<PrinterConfig> printerConfigs;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
Log log = getLog();
String logLevel = log.isDebugEnabled() ? "DEBUG" : log.isWarnEnabled() ? "WARN" : log.isInfoEnabled() ? "INFO" : "ERROR";
log.info("Log level is "+logLevel);
log.debug(config.toString());
try {
ClassLoader classLoader = getClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
Class<?> lazyDocClass = classLoader.loadClass("org.lazydoc.LazyDoc");
Class<?> lazyDocConfigClass = classLoader.loadClass("org.lazydoc.config.Config");
Class<?> lazyDocPrinterConfigClass = classLoader.loadClass("org.lazydoc.config.PrinterConfig");
Object lazydocConfig = lazyDocConfigClass.newInstance();
BeanUtils.copyProperties(lazydocConfig, config);
List lazyDocPrinterConfigs = new ArrayList();
if (printerConfigs != null) {
for(PrinterConfig printerConfig : printerConfigs) {
Object lazydocPrinterConfig = lazyDocPrinterConfigClass.newInstance();
BeanUtils.copyProperties(lazydocPrinterConfig, printerConfig);
lazyDocPrinterConfigs.add(lazydocPrinterConfig);
}
}
lazyDocClass.getDeclaredMethod("document", lazyDocConfigClass, List.class, String.class).invoke(lazyDocClass.newInstance(), lazydocConfig, lazyDocPrinterConfigs, logLevel);
} catch (Exception e) {
getLog().error("Error parsing for documentation.", e);
throw new MojoFailureException("Error parsing for documentation." + e.getMessage());
}
}
private ClassLoader getClassLoader()
throws MojoExecutionException, DependencyResolutionRequiredException {
List<URL> classpathURLs = new ArrayList<URL>();
this.addRelevantPluginDependenciesToClasspath(classpathURLs);
this.addRelevantProjectDependenciesToClasspath(classpathURLs);
for (URL classpath : classpathURLs) {
getLog().debug("Classpath: " + classpath.toString());
}
return new URLClassLoader(classpathURLs.toArray(new URL[classpathURLs.size()]));
}
private void addRelevantPluginDependenciesToClasspath(List<URL> path)
throws MojoExecutionException {
try {
for (Artifact classPathElement : new HashSet<Artifact>(this.pluginDependencies)) {
URL url = classPathElement.getFile().toURI().toURL();
getLog().debug("Adding plugin dependency artifact: " + classPathElement.getArtifactId()
+ " to classpath ("+url+")");
path.add(url);
}
} catch (MalformedURLException e) {
throw new MojoExecutionException("Error during setting up classpath", e);
}
}
private void addRelevantProjectDependenciesToClasspath(List<URL> path)
throws MojoExecutionException, DependencyResolutionRequiredException {
try {
getLog().debug("Project Dependencies will be included.");
List<Artifact> artifacts = new ArrayList<Artifact>();
List<File> theClasspathFiles = new ArrayList<File>();
collectProjectArtifactsAndClasspath(artifacts, theClasspathFiles);
for (File classpathFile : theClasspathFiles) {
URL url = classpathFile.toURI().toURL();
getLog().debug("Adding to classpath : " + url);
path.add(url);
}
for (Artifact classPathElement : artifacts) {
getLog().debug("Artifact: "+classPathElement);
getLog().debug("Artifact file: "+classPathElement.getFile());
URL url = classPathElement.getFile().toURI().toURL();
getLog().debug("Adding project dependency artifact: " + classPathElement.getArtifactId()
+ " to classpath ("+url+")");
path.add(url);
}
} catch (MalformedURLException e) {
throw new MojoExecutionException("Error during setting up classpath", e);
}
}
@SuppressWarnings("unchecked")
protected void collectProjectArtifactsAndClasspath(List<Artifact> artifacts, List<File> theClasspathFiles) throws MojoExecutionException, DependencyResolutionRequiredException {
artifacts.addAll(project.getCompileDependencies());
artifacts.addAll(resolveProjectDependencies(project.getDependencies()));
theClasspathFiles.add(new File(project.getBuild().getOutputDirectory()));
getLog().debug("Collected project artifacts " + artifacts);
getLog().debug("Collected project classpath " + theClasspathFiles);
}
private Set<Artifact> resolveProjectDependencies(List<Dependency> dependencies) throws MojoExecutionException {
Set<Artifact> resolvedArtifacts = new HashSet<>();
try {
getLog().debug("Project dependencies: "+dependencies);
// make Artifacts of all the dependencies
Set<Artifact> dependencyArtifacts = MavenMetadataSource.createArtifacts(this.artifactFactory, dependencies, null, null, null);
getLog().debug("Artifacts build from dependencies: "+dependencyArtifacts);
for (Artifact dependencyArtifact : dependencyArtifacts) {
artifactResolver.resolve(dependencyArtifact, this.remoteRepositories, this.localRepository);
ArtifactResolutionResult result = artifactResolver.resolveTransitively(dependencyArtifacts, dependencyArtifact, this.remoteRepositories, this.localRepository, this.metadataSource);
resolvedArtifacts.addAll(result.getArtifacts());
}
resolvedArtifacts.addAll(dependencyArtifacts);
return resolvedArtifacts;
} catch (Exception ex) {
throw new MojoExecutionException("Encountered problems resolving dependencies of the executable "
+ "in preparation for its execution.", ex);
}
}
}